import { useWindowSize } from '@vueuse/core';
import type { App, InjectionKey, Ref } from 'vue';
import { inject, readonly } from 'vue';

const screenWidthInjectionKey = Symbol('screenWidthInjectionKey') as InjectionKey<
  Readonly<Ref<number>>
>;
const screenHeightInjectionKey = Symbol('screenHeightInjectionKey') as InjectionKey<
  Readonly<Ref<number>>
>;
const vhInjectionKey = Symbol('vhInjectionKey') as InjectionKey<(px: number) => number>;
const vwInjectionKey = Symbol('vwInjectionKey') as InjectionKey<(px: number) => number>;

export type ViewPortFn = (px: number) => number;

/**
 * 屏幕适配  设计稿高度/可视高度*px
 */
export function useVh(): ViewPortFn {
  return inject(vhInjectionKey)!;
}

/**
 * 屏幕适配  设计稿宽度/可视宽度*px
 */
export function useVw(): ViewPortFn {
  return inject(vwInjectionKey)!;
}

/**
 * 屏幕适配
 * @param height 设计稿高度
 * @param width 设计稿宽度
 * @returns
 */
export function createViewPortPlugin(height = 1080, width = 1920) {
  const { width: screenWidth, height: screenHeight } = useWindowSize();

  function vh(px: number) {
    return +((screenHeight.value / height) * px).toFixed();
  }
  function vw(px: number) {
    return +((screenWidth.value / width) * px).toFixed();
  }
  return {
    install(app: App) {
      app.provide(screenWidthInjectionKey, screenWidth);
      app.provide(screenHeightInjectionKey, screenHeight);
      app.provide(vhInjectionKey, vh);
      app.provide(vwInjectionKey, vw);
      Object.defineProperties(app.config.globalProperties, {
        $screenWidth: {
          enumerable: true,
          get: () => readonly(screenWidth),
        },
        $screenHeight: {
          enumerable: true,
          get: () => readonly(screenHeight),
        },
        $vh: {
          enumerable: true,
          get: () => vh,
        },
        $vw: {
          enumerable: true,
          get: () => vw,
        },
      });
    },
  };
}

declare module '@vue/runtime-core' {
  export interface ComponentCustomProperties {
    /**
     * 浏览器宽信息
     */
    $screenWidth: Readonly<Ref<number>>;
    /**
     * 浏览器高信息
     */
    $screenHeight: Readonly<Ref<number>>;

    /**
     * 屏幕适配  设计稿高度/可视高度*px
     */
    $vh: (px: number) => number;

    /**
     * 屏幕适配  设计稿宽度/可视宽度*px
     */
    $vw: (px: number) => number;
  }
}
